package com.aabte.lota.auth;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.LongSerializationPolicy;
import java.lang.reflect.Type;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.spring.web.json.Json;

/**
 * WebMvcConfig
 *
 * <p>也可通过继承{@link WebMvcConfigurationSupport}
 *
 * <p>需要注意的是，一个项目中最好只有一个WebMvc配置类
 *
 * @author Daniel
 * @version 1.0
 * @date 2020/3/29
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

  /**
   * 如果出现无法排除jackson等特殊情况， 通过重写extendMessageConverters方法来使
   * getMessageConverters方法返回一个修改过的messageConverters
   */
  @Override
  public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.removeIf(
        httpMessageConverter ->
            httpMessageConverter instanceof MappingJackson2HttpMessageConverter);
    converters.removeIf(
        httpMessageConverter -> httpMessageConverter instanceof GsonHttpMessageConverter);
    converters.add(gsonHttpMessageConverter());
  }

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    // 静态资源
    registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    // swagger静态资源
    registry
        .addResourceHandler("swagger-ui.html")
        .addResourceLocations("classpath:/META-INF/resources/");
    registry
        .addResourceHandler("/webjars/**")
        .addResourceLocations("classpath:/META-INF/resources/webjars/");
    // SwaggerBootstrapUI路径
    registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
  }

  /** Geson序列化支持 */
  @Bean
  public GsonHttpMessageConverter gsonHttpMessageConverter() {
    GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
    converter.setGson(gson());
    return converter;
  }

  private Gson gson() {
    return new GsonBuilder()
        .registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter())
        .setLongSerializationPolicy(LongSerializationPolicy.STRING)
        .create();
  }

  public static class SpringfoxJsonToGsonAdapter implements JsonSerializer<Json> {

    @Override
    public JsonElement serialize(Json json, Type type, JsonSerializationContext context) {
      return JsonParser.parseString(json.value());
    }
  }
}
